package com.mvc.core;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.mvc.annotation.Controller;
import com.mvc.annotation.RequestMapping;

/**
 * 处理器映射器
 * @author david
 *
 */
public class HandlerMapping {

	private Map<String, Object> ioc = new HashMap<String, Object>();//ico容器,Map<类名, Object 实例>
	private Map<String, Object> urlMappings = new HashMap<String, Object>();//请求映射容器,Map<url, 实例>
	private Map<String, Method> urlMethods = new HashMap<String, Method>();//请求映射容器,Map<url, 方法>

	/**
	 * 根据控制层组件的类名，初始化一个Ioc容器
	 * @param classNameList
	 */
	public void initIoc(List<String> classNameList) {
		if(classNameList.isEmpty()) return;
		
		try {
			for (String className : classNameList) {
				Class<?> cls = Class.forName(className);
				
				if(cls.isAnnotationPresent(Controller.class)) {
					Object obj = cls.getDeclaredConstructor().newInstance();
					ioc.put(className, obj);
				}
			}
		} catch(Exception e){
			System.out.println("500 initIoc exception");
			e.printStackTrace();
		} finally {
			
		}
		
	}
	
	/**
	 * 建立 请求映射路径->实例, 请求映射路径->Method的映射
	 */
	public void initMappings() {
		String baseUrl = "", url  = "";
		Set<Entry<String, Object>> set = ioc.entrySet();
		
		for (Entry<String, Object> entry : set) {
			Object obj = entry.getValue();
			Class<?> cls = obj.getClass();
			
			//判断类上面是否加了RequestMapping注解
			if(cls.isAnnotationPresent(RequestMapping.class)) {
				RequestMapping mapping = cls.getDeclaredAnnotation(RequestMapping.class);
				baseUrl  = mapping.value();
				
			}
			
			Method[] methods = cls.getDeclaredMethods();
			for (Method m:methods) {
				if(m.isAnnotationPresent(RequestMapping.class)) {
					url = baseUrl + m.getDeclaredAnnotation(RequestMapping.class).value();
					urlMethods.put(url, m); // /comment/save.do   CommentController中某个Method
					urlMappings.put(url, obj);// /comment/save.do   CommentController实例
				}
			}
		}
	}

	
	public Map<String, Object> getIoc() {
		return ioc;
	}

	public void setIoc(Map<String, Object> ioc) {
		this.ioc = ioc;
	}
	
	public Map<String, Object> getUrlMappings() {
		return urlMappings;
	}

	public void setUrlMappings(Map<String, Object> urlMappings) {
		this.urlMappings = urlMappings;
	}
	
	public Map<String, Method> getUrlMethods() {
		return urlMethods;
	}

	public void setUrlMethods(Map<String, Method> urlMethods) {
		this.urlMethods = urlMethods;
	}
}
